using System.Collections;
using System.Collections.Generic;
using JetBrains.Annotations;
using QFramework;
using Unity.VisualScripting;
using UnityEngine;
namespace ProjectSurvivor
{
    public class Global : Architecture<Global>
    {
        //数据全部清空
        #if UNITY_EDITOR
        [UnityEditor.MenuItem("Tool/Clear All Data")]
        public static void ClearAllData()
        {
            PlayerPrefs.DeleteAll();
        }
        #endif
        #region  Model
        //可绑定属性
        public static BindableProperty<int> HP = new BindableProperty<int>(3);
        public static BindableProperty<int> MaxHp = new BindableProperty<int>(3);
        /// <summary>
        /// 经验值
        /// </summary>
        public static BindableProperty<int> Exp = new BindableProperty<int>(5);
        public static BindableProperty<int> Coin = new BindableProperty<int>(0);
        /// <summary>
        /// 等级
        /// </summary>
        public static BindableProperty<int> Level = new BindableProperty<int>(1);
        /// <summary>
        /// 当前秒数
        /// </summary>
        public static BindableProperty<float> CurrentSeconds = new BindableProperty<float>(0);
        public static BindableProperty<bool> SimpleSwordUnlocked = new BindableProperty<bool>(false);
        /// <summary>
        /// 简单能力伤害
        /// </summary>
        public static BindableProperty<float> SimpleAbilityDamage = new(Config.InitSimpleSwordDamage);
        /// <summary>
        /// 简单能力持续时间
        /// </summary>
        public static BindableProperty<float> SimpleAbilityDuration = new(Config.InitSimpleSwordDuration);
        /// <summary>
        /// 简单剑数
        /// </summary>
        public static BindableProperty<int> SimpleSwordCount = new(Config.InitSimpleSwordCount);
        /// <summary>
        /// 简单剑范围
        /// </summary>
        public static BindableProperty<float> SimpleSwordRange = new(Config.InitSimpleSwordRange);
        /// <summary>
        /// 简单能力是否解锁
        /// </summary>
        
        public static BindableProperty<bool> BombUnlocked = new BindableProperty<bool>(false);
        /// <summary>
        /// 炸弹伤害
        /// </summary>
        public static BindableProperty<float> BombDamage = new(Config.InitBombDamage);
        /// <summary>
        /// 炸弹持续时间
        /// </summary>
        public static BindableProperty<float> BombPercent = new(Config.InitBombPercent);
        /// <summary>
        /// 炸弹是否解锁
        /// </summary>

        public static BindableProperty<bool> SimpleKnifeUnlocked = new BindableProperty<bool>(false);
        /// <summary>
        /// 简单刀伤害
        /// </summary>
        public static BindableProperty<float> SimpleKnifeDamage = new BindableProperty<float>(Config.InitSimpleKnifeDamage);
        /// <summary>
        /// 简单刀持续时间
        /// </summary>
        public static BindableProperty<float> SimpleKnifeDuration = new BindableProperty<float>(Config.InitSimpleKnifeDuration);
        /// <summary>
        /// 简单刀具攻击次数
        /// </summary>
        public static BindableProperty<int> SimpleKnifeAttackCount = new BindableProperty<int>(1);
        /// <summary>
        /// 简单刀具攻击次数
        /// </summary>
        public static BindableProperty<int> SimpleKnifeCount = new BindableProperty<int>(Config.InitSimpleKnifeCount);

        /// <summary>
        /// 旋转剑是否解锁
        /// </summary>
        public static BindableProperty<bool> RotateSwordUnlocked = new BindableProperty<bool>(false);
        /// <summary>
        /// 旋转剑伤害
        /// </summary>
        public static BindableProperty<float> RotateSwordDamage = new(Config.InitRotateSwordDamage);
        /// <summary>
        /// 旋转剑攻击次数
        /// </summary>
        public static BindableProperty<int> RotateSwordCount = new(Config.InitRotateSwordCount);
        /// <summary>
        /// 旋转剑速度
        /// </summary>
        public static BindableProperty<float> RotateSwordSpeed = new(Config.InitRotateSwordSpeed);
        /// <summary>
        /// 旋转剑范围
        /// </summary>
        public static BindableProperty<float> RotateSwordRange = new(Config.InitRotateSwordRange);
        /// <summary>
        /// 旋转剑是否解锁
        /// </summary>

        public static BindableProperty<bool> BasketBallUnlocked = new BindableProperty<bool>(false);
        /// <summary>
        /// 篮球伤害
        /// </summary>
        public static BindableProperty<float> BasketBallDamage = new(Config.InitBasketBallDamage);
        /// <summary>
        /// 篮球速度
        /// </summary>
        public static BindableProperty<float> BasketBallSpeed = new(Config.InitBasketBallSpeed);
        /// <summary>
        /// 篮球攻击次数
        /// </summary>
        public static BindableProperty<int> BasketBallCount = new(Config.InitBasketBallCount);
        /// <summary>
        /// 暴击概率
        /// </summary>
        public static BindableProperty<float> CriticalRate = new BindableProperty<float>(Config.InitCriticalRate);
        /// <summary>
        /// 伤害加成
        /// </summary>
        public static BindableProperty<float>DamageRate=new(1);
        /// <summary>
        /// 额外飞行物数量
        /// </summary>
        public static BindableProperty<int> AdditionalFlyThingCount=new(0);
        /// <summary>
        /// 移动速度加成
        /// </summary>
        public static BindableProperty<float>MovementSpeedRate=new(1.0f);
        /// <summary>
        /// 收集范围
        /// </summary>
        public static BindableProperty<float> CollectableArea = new(Config.InitCollectableArea);
        /// <summary>
        /// 额外经验值百分比
        /// </summary>
        public static BindableProperty<float> AdditionalExpPercent = new(0);
        /// <summary>
        /// 超级刀是否解锁
        /// </summary>
        public static BindableProperty<bool>SuperKnife=new(false);
        /// <summary>
        /// 超级刀伤害
        /// </summary>
        public static BindableProperty<bool> SuperSword=new(false);
        /// <summary>
        /// 超级炸弹是否解锁
        /// </summary>
        public static BindableProperty<bool> SuperBomb=new(false);
        /// <summary>
        /// 超级炸弹伤害
        /// </summary>
        public static BindableProperty<bool> SuperRotateSword=new(false);
        /// <summary>
        /// 超级炸弹是否解锁
        /// </summary>
        public static BindableProperty<bool> SuperBasketBall=new(false);

        /// <summary>
        /// 经验百分比
        /// </summary>
        public static BindableProperty<float> ExPercent = new BindableProperty<float>(0.3f);
        /// <summary>
        /// 金币百分比
        /// </summary>
        public static BindableProperty<float> CoinPercent = new BindableProperty<float>(0.05f);
        #endregion
        //自动初始化
        //在游戏启动时自动调用
        //早于Awake
        [RuntimeInitializeOnLoadMethod]
        public static void AutoInit()
        {
            //忽略全局帧中的相同音素
            AudioKit.PlaySoundMode=AudioKit.PlaySoundModes.IgnoreSameSoundInGlobalFrames;
            //资源初始化
            ResKit.Init();
            //UI初始化                          屏幕的缩放因子
            UIKit.Root.SetResolution(1920, 1080, 1);
            Global.MaxHp.Value = PlayerPrefs.GetInt(nameof(MaxHp), 3);
            HP.Value = MaxHp.Value;
            Global.Coin.Value = PlayerPrefs.GetInt("coin", 0);
            Global.ExPercent.Value = PlayerPrefs.GetFloat(nameof(ExPercent), 0.4f);
            Global.CoinPercent.Value = PlayerPrefs.GetFloat(nameof(CoinPercent), 0.1f);
            //注册事件
            Global.Coin.Register(coin =>
            {
                //nameof 是一个用于获取代码元素名称的运算符
                PlayerPrefs.SetInt(nameof(coin), coin);
            });
            Global.ExPercent.Register(expPercent =>
            {
                PlayerPrefs.SetFloat(nameof(expPercent), expPercent);
            });
            Global.CoinPercent.Register(coinPercent =>
            {
                PlayerPrefs.SetFloat(nameof(coinPercent), coinPercent);
            });
            Global.MaxHp.Register(maxHp =>
            {
                PlayerPrefs.SetInt(nameof(maxHp), maxHp);
            });
            //升级调用得时候才会对这个架构进行初始化，所以这里初始化一下
            var _ = Interface;
        }

        /// <summary>
        /// 重新赋值
        /// </summary>
        public static void ResetData()
        {
            HP.Value = MaxHp.Value;
            Exp.Value = 0;
            Level.Value = 1;
            CurrentSeconds.Value = 0;
            SimpleSwordUnlocked.Value = false;
            SimpleAbilityDamage.Value = Config.InitSimpleSwordDamage;
            SimpleAbilityDuration.Value = Config.InitSimpleSwordDuration;
            SimpleSwordRange.Value = Config.InitSimpleSwordRange;
            SimpleSwordCount.Value = Config.InitSimpleSwordCount;

            BombPercent.Value = Config.InitBombPercent;
            BombDamage.Value = Config.InitBombDamage;
            BombUnlocked.Value = false;

            SimpleKnifeUnlocked.Value = false;
            SimpleKnifeDamage.Value = Config.InitSimpleKnifeDamage;
            SimpleKnifeDuration.Value = Config.InitSimpleKnifeDuration;
            SimpleKnifeCount.Value = Config.InitSimpleKnifeCount;
            SimpleKnifeAttackCount.Value = 1;
            RotateSwordUnlocked.Value = false;
            RotateSwordDamage.Value = Config.InitRotateSwordDamage;
            RotateSwordCount.Value = Config.InitRotateSwordCount;
            RotateSwordSpeed.Value = Config.InitRotateSwordSpeed;
            RotateSwordRange.Value = Config.InitRotateSwordRange;
            BasketBallUnlocked.Value = false;
            BasketBallDamage.Value = Config.InitBasketBallDamage;
            BasketBallSpeed.Value = Config.InitBasketBallSpeed;
            BasketBallCount.Value = Config.InitBasketBallCount;

            CriticalRate.Value=Config.InitCriticalRate;
            DamageRate.Value=1;
            AdditionalFlyThingCount.Value=0;
            MovementSpeedRate.Value=1.0f;
            CollectableArea.Value=Config.InitCollectableArea;
            AdditionalExpPercent.Value=0;

            SuperKnife.Value=false;
            SuperSword.Value=false;
            SuperBomb.Value=false;
            SuperRotateSword.Value=false;
            SuperBasketBall.Value=false;

            //敌人
            EnemyGenerator.EnemyCount.Value = 0;
            Interface.GetSystem<ExpUpgradeSystem>().ResetData();
        }
        //升级到下一级所需经验
        public static int ExpToNextLevel()
        {
            return Level.Value * 5;
        }
        /// <summary>
        /// 怪物死亡几率掉落
        /// </summary>
        /// <param name="gameObject"></param>
        public static void GeneratePowerUp(GameObject gameObject,bool genTreasureChest)
        {
            //掉落宝箱
            if(genTreasureChest)
            {
                PowerUpManager.Default.TreasureChest.Instantiate().Position(gameObject.Position()).Show();
                return;
            }
            //90%掉落经验值
            var percent = Random.Range(0, 1f);
            if (percent < ExPercent.Value+AdditionalExpPercent.Value)
            {
                //掉落经验值
                PowerUpManager.Default.Exp.Instantiate().Position(gameObject.Position()).Show();
                return;
            }
            percent = Random.Range(0, 1f);
            if (percent < CoinPercent.Value)
            {
                PowerUpManager.Default.Coin.Instantiate().Position(gameObject.Position()).Show();
                return;
            }

            percent = Random.Range(0, 1f );
            if (percent < 0.1F&& !Object.FindObjectOfType<HP>())
            {
                PowerUpManager.Default.HP.Instantiate().Position(gameObject.Position()).Show();
                return;
            }
            if (BombUnlocked.Value && !Object.FindObjectOfType<Bomb>())
            {
                percent = Random.Range(0, 1f);
                if (percent < BombPercent.Value)
                {
                    PowerUpManager.Default.Bomb.Instantiate().Position(gameObject.Position()).Show();
                    return;
                }
            }
            percent = Random.Range(0, 1f);
            if (percent < 0.1F&& !Object.FindObjectOfType<GetAllExp>())
            {
                PowerUpManager.Default.GetAllExp.Instantiate().Position(gameObject.Position()).Show();
                return;
            }
        }

        protected override void Init()
        {
            //注册模块的制作
            //XXX Model
            this.RegisterSystem(new SaveSystem());
            this.RegisterSystem(new CoinUpgradeSystem());
            this.RegisterSystem(new ExpUpgradeSystem());
            //成就系统
            this.RegisterSystem(new AchievementSystem());
        }
    }
}